PV console for HVM domains
authorStefano Stabellini <sstabellini@xensource.com>
Thu, 5 Aug 2010 10:36:24 +0000 (11:36 +0100)
committerStefano Stabellini <sstabellini@xensource.com>
Thu, 5 Aug 2010 10:36:24 +0000 (11:36 +0100)
Creates a shared memory ring buffer and event channel in HVM domains
for passing debug messages from PV drivers on HVM guests
The console is used by windows pv drivers to send debug data to xenconsoled

Signed-off-by: Owen Smith <owen.smith@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
tools/libxc/xc_domain_restore.c
tools/libxc/xc_domain_save.c
tools/libxc/xc_hvm_build.c
tools/libxl/libxl_dom.c
tools/libxl/libxl_internal.h
tools/libxl/xenguest.c
tools/libxl/xl_cmdimpl.c
xen/include/public/hvm/params.h

index 129365c42f21b261448e864bde8c6c0828f73e4b..3fd03307147638e3df5f09e3d9abb6ef7b24aa58 100644 (file)
@@ -640,6 +640,7 @@ typedef struct {
     uint64_t vcpumap;
     uint64_t identpt;
     uint64_t vm86_tss;
+    uint64_t console_pfn;
 } pagebuf_t;
 
 static int pagebuf_init(pagebuf_t* buf)
@@ -737,6 +738,16 @@ static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx,
             return -1;
         }
         return pagebuf_get_one(xch, ctx, buf, fd, dom);
+    } else if (count == -8 ) {
+        /* Skip padding 4 bytes then read the console pfn location. */
+        if ( read_exact(fd, &buf->console_pfn, sizeof(uint32_t)) ||
+             read_exact(fd, &buf->console_pfn, sizeof(uint64_t)) )
+        {
+            PERROR("error read the address of the console pfn");
+            return -1;
+        }
+        // DPRINTF("console pfn location: %llx\n", buf->console_pfn);
+        return pagebuf_get_one(xch, ctx, buf, fd, dom);
     } else if ( (count > MAX_BATCH_SIZE) || (count < 0) ) {
         ERROR("Max batch size exceeded (%d). Giving up.", count);
         errno = EMSGSIZE;
@@ -1055,6 +1066,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
     pagebuf_t pagebuf;
     tailbuf_t tailbuf, tmptail;
     void* vcpup;
+    uint64_t console_pfn = 0;
 
     static struct restore_ctx _ctx = {
         .live_p2m = NULL,
@@ -1207,6 +1219,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                 xc_set_hvm_param(xch, dom, HVM_PARAM_IDENT_PT, pagebuf.identpt);
             if ( pagebuf.vm86_tss )
                 xc_set_hvm_param(xch, dom, HVM_PARAM_VM86_TSS, pagebuf.vm86_tss);
+            if ( pagebuf.console_pfn )
+                console_pfn = pagebuf.console_pfn;
             break;  /* our work here is done */
         }
 
@@ -1717,6 +1731,19 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
     }
     *store_mfn = tailbuf.u.hvm.magicpfns[2];
 
+    if ( console_pfn ) {
+        if ( xc_clear_domain_page(xch, dom, console_pfn) ) {
+            PERROR("error zeroing console page");
+            goto out;
+        }
+        if ( (frc = xc_set_hvm_param(xch, dom, 
+                                    HVM_PARAM_CONSOLE_PFN, console_pfn)) ) {
+            PERROR("error setting HVM param: %i", frc);
+            goto out;
+        }
+        *console_mfn = console_pfn;
+    }
+
     frc = xc_domain_hvm_setcontext(xch, dom, tailbuf.u.hvm.hvmbuf,
                                    tailbuf.u.hvm.reclen);
     if ( frc )
index cc6bd1318e68464f7f3593b20afe31498593a8f3..2ea22724068fbd86b1f83c3e9969c16c725963b4 100644 (file)
@@ -1587,6 +1587,17 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
             PERROR("Error when writing the vm86 TSS for guest");
             goto out;
         }
+
+        chunk.id = -8;
+        xc_get_hvm_param(xch, dom, HVM_PARAM_CONSOLE_PFN,
+                         (unsigned long *)&chunk.data);
+
+        if ( (chunk.data != 0) &&
+             wrexact(io_fd, &chunk, sizeof(chunk)) )
+        {
+            PERROR("Error when writing the console pfn for guest");
+            goto out;
+        }
     }
 
     /* Zero terminate */
index 4fc5f6d63e717916a36197c02ddb01979fa5b360..7bdd50b1f3d4e57fc72802433be904d2c1735f27 100644 (file)
@@ -28,7 +28,8 @@
 #define SPECIALPAGE_XENSTORE 1
 #define SPECIALPAGE_IOREQ    2
 #define SPECIALPAGE_IDENT_PT 3
-#define NR_SPECIAL_PAGES     4
+#define SPECIALPAGE_CONSOLE  4
+#define NR_SPECIAL_PAGES     5
 #define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x))
 
 static void build_hvm_info(void *hvm_info_page, uint64_t mem_size)
@@ -354,6 +355,8 @@ static int setup_guest(xc_interface *xch,
                      special_pfn(SPECIALPAGE_BUFIOREQ));
     xc_set_hvm_param(xch, dom, HVM_PARAM_IOREQ_PFN,
                      special_pfn(SPECIALPAGE_IOREQ));
+    xc_set_hvm_param(xch, dom, HVM_PARAM_CONSOLE_PFN,
+                     special_pfn(SPECIALPAGE_CONSOLE));
 
     /*
      * Identity-map page table is required for running with CR0.PG=0 when
index b251d8aa4ed6cb23180fc3af38f268485c8a16b8..2c1b5351e6e51fd9ffafdb993d06367020e5a40a 100644 (file)
@@ -237,7 +237,7 @@ int build_hvm(libxl_ctx *ctx, uint32_t domid,
         return ERROR_FAIL;
     }
     ret = hvm_build_set_params(ctx->xch, domid, info, state->store_port,
-                               &state->store_mfn);
+                               &state->store_mfn, state->console_port, &state->console_mfn);
     if (ret) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "hvm build set params failed");
         return ERROR_FAIL;
index 3f0454468ae0dff5e98b2a38a481d860ce17ccf5..dde37df1aa2127942d78780f357f021aa5e29f60 100644 (file)
@@ -173,7 +173,8 @@ int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int bus
 /* from xenguest (helper */
 int hvm_build_set_params(xc_interface *handle, uint32_t domid,
                          libxl_domain_build_info *info,
-                         int store_evtchn, unsigned long *store_mfn);
+                         int store_evtchn, unsigned long *store_mfn,
+                         int console_evtchn, unsigned long *console_mfn);
 
 /* xl_exec */
 
index 1f88b8a23acd5b83ae37d836664b5eb694cf5ce7..9351f23e811420f67c16fea21d9fc69426fb11e1 100644 (file)
@@ -23,7 +23,8 @@
 
 int hvm_build_set_params(xc_interface *handle, uint32_t domid,
                          libxl_domain_build_info *info,
-                         int store_evtchn, unsigned long *store_mfn)
+                         int store_evtchn, unsigned long *store_mfn,
+                         int console_evtchn, unsigned long *console_mfn)
 {
     struct hvm_info_table *va_hvm;
     uint8_t *va_map, sum;
@@ -46,6 +47,7 @@ int hvm_build_set_params(xc_interface *handle, uint32_t domid,
     munmap(va_map, XC_PAGE_SIZE);
 
     xc_get_hvm_param(handle, domid, HVM_PARAM_STORE_PFN, store_mfn);
+    xc_get_hvm_param(handle, domid, HVM_PARAM_CONSOLE_PFN, console_mfn);
     xc_set_hvm_param(handle, domid, HVM_PARAM_PAE_ENABLED, info->u.hvm.pae);
 #if defined(__i386__) || defined(__x86_64__)
     xc_set_hvm_param(handle, domid, HVM_PARAM_VIRIDIAN, info->u.hvm.viridian);
@@ -54,5 +56,6 @@ int hvm_build_set_params(xc_interface *handle, uint32_t domid,
     xc_set_hvm_param(handle, domid, HVM_PARAM_TIMER_MODE, (unsigned long) info->u.hvm.timer_mode);
     xc_set_hvm_param(handle, domid, HVM_PARAM_VPT_ALIGN, (unsigned long) info->u.hvm.vpt_align);
     xc_set_hvm_param(handle, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn);
+    xc_set_hvm_param(handle, domid, HVM_PARAM_CONSOLE_EVTCHN, console_evtchn);
     return 0;
 }
index 51d9f4b31c9db0543f0452ef9d5b333ccc3c022b..e42ad69cbe0701727209073f924e603ca2cc6d00 100644 (file)
@@ -1433,6 +1433,9 @@ start:
         }
     }
     if (d_config.c_info.hvm) {
+        init_console_info(&console, 0, &state);
+        console.domid = domid;
+        libxl_device_console_add(&ctx, domid, &console);
         dm_info.domid = domid;
         MUST( libxl_create_device_model(&ctx, &dm_info,
                                         d_config.disks, d_config.num_disks,
index 7e276d92e09d36bd1d2d10cb4a944094a402e4b6..673148bbfa28ff7fc3e44a60cb0d439fad8baa6c 100644 (file)
 /* Boolean: Enable aligning all periodic vpts to reduce interrupts */
 #define HVM_PARAM_VPT_ALIGN    16
 
-#define HVM_NR_PARAMS          17
+/* Console debug shared memory ring and event channel */
+#define HVM_PARAM_CONSOLE_PFN    17
+#define HVM_PARAM_CONSOLE_EVTCHN 18
+
+#define HVM_NR_PARAMS          19
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */